home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / blix / blixscore.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  14.8 KB  |  621 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*_______________________________________________________________________
  18.  |
  19.  | blixscore.c - handles reading and writing highscores
  20.  |
  21.  | There are three levels of highscore stored at different places
  22.  | the first level is in the users home directory to store the personal
  23.  | highscores. The second is stored in "/usr/tmp/Indyzone/blix" and
  24.  | holds the systemwide scores. The third - more interesting level - 
  25.  | holds the worldwide records (for people who can reach the server)
  26.  | The format of the file is the same in all three cases.
  27.  |
  28.  | (c) 1994 Frans van Hoesel, hoesel@chem.rug.nl
  29.  |               Xtreme Graphics Software
  30.  |
  31. */
  32.  
  33. #include <pwd.h>
  34. #include <stdio.h>
  35. #include <sys/types.h>
  36. #include <sys/stat.h>
  37. #include <netinet/in.h>
  38. #include <netdb.h>
  39. #include <unistd.h>
  40. #include <string.h>
  41. #include <malloc.h>
  42. #include <alloca.h>
  43. #include <fcntl.h>
  44. #include <bstring.h>
  45. #include <stdlib.h>
  46.  
  47. #include "blix.h"
  48. #include "blixnetwork.h"
  49. #include "blixscore.h"
  50. #include "blixscore_io.h"
  51. #include "blixtmpdir.h"
  52. #include "blixui.h"
  53.  
  54. int gethostname (char *name, int namelen);
  55. int world_score_id;
  56.  
  57. scorelist_t privatlist;
  58. scorelist_t systemlist;
  59. scorelist_t worldlist;
  60.  
  61. static int updatescore(scorelist_t *scorelist, userinfo_t *inf) ;
  62. static void sort_score(scorelist_t *scorelist);
  63. static int doprivatescore(userinfo_t *inf);
  64. static int dosystemscore(userinfo_t *inf);
  65. static int doworldscore(userinfo_t *inf);
  66.  
  67. int sginap(long ticks);
  68.  
  69. void init_tmpdir(void) {
  70.     mode_t cmask;
  71.     int f;
  72.  
  73.     cmask = umask(0000);
  74.     f = open(BLIXTMPDIR, O_RDONLY) ;
  75.     if (f == -1) {
  76.     /* directory does not exists; make it */
  77.     mkdir(TMPDIR1, 0777);
  78.     if (mkdir(BLIXTMPDIR, 0777)) {
  79.         fprintf(stderr,"%s: Cannot create directory '" BLIXTMPDIR "' "
  80.             "for writing temporary data\n", basename );
  81.         cmask = umask(cmask);
  82.         exit(1);
  83.     }
  84.     } else {
  85.     close(f);
  86.     }
  87.     cmask = umask(cmask);
  88. }
  89.  
  90. static int openprivatscore(void) {
  91.     userinfo_t *inf;
  92.     char *name;
  93.     int f;
  94.     
  95.     inf = getinf();
  96.     if (inf == NULL) {
  97.     return 0;
  98.     }
  99.     name = (char *)alloca((strlen(inf->home) + 13) * sizeof(char));
  100.     strcpy(name, inf->home);
  101.     strcat(name, "/.blixscore");
  102.     f = openscore(name, 3);
  103.     return f;
  104. }
  105.  
  106. static int opensystemscore(void) {
  107.     
  108.     mode_t cmask;
  109.     int f;
  110.  
  111.     cmask = umask(0111);    
  112.     f = openscore(BLIXTMPDIR "/systemscore", 15);
  113.     cmask = umask(cmask);
  114.     if (f == -1) {
  115.     fprintf(stderr,"%s: Cannot create file %s\n", basename,
  116.         BLIXTMPDIR "/systemscore");
  117.     } 
  118.     return f;
  119. }
  120.  
  121. static int openworldscore(void) {
  122.     
  123.     mode_t cmask;
  124.     int f;
  125.  
  126.     cmask = umask(0111);    
  127.     f = openscore(BLIXTMPDIR "/worldcache", 15);
  128.     cmask = umask(cmask);
  129.     if (f == -1) {
  130.     fprintf(stderr,"%s: Cannot create file %s\n", basename,
  131.         BLIXTMPDIR "/worldcache");
  132.     } 
  133.     return f;
  134. }
  135.  
  136. userinfo_t *getinf(void) {
  137.     
  138.     struct passwd *pass;
  139.     struct hostent *hostinfo;
  140.     static userinfo_t uinfo;
  141.     static int done_it = 0;
  142.     char name[256];
  143.     char *cptr;
  144.     char alias[50];
  145.     FILE *f;
  146.     char *s;
  147.      
  148.     if (done_it) {
  149.     return &uinfo;
  150.     }
  151.     done_it = 1;
  152.     cptr = cuserid(NULL);
  153.     if (cptr == NULL) {
  154.     cptr = getlogin();
  155.     }
  156.  
  157.     if (cptr == NULL) {
  158.     fprintf(stderr,"%s: Cannot find your login name\n", basename);
  159.     return NULL;
  160.     }
  161.     strncpy(uinfo.name, cptr, 47);
  162.     uinfo.name[47] = '\0';
  163.     pass = getpwuid(getuid());
  164.     if (pass != NULL && pass->pw_dir != NULL && *(pass->pw_dir) != '\0') {
  165.     strncpy(uinfo.home, pass->pw_dir, 47);
  166.     uinfo.home[47] = '\0';
  167.     strncpy(uinfo.name, pass->pw_name, 47);
  168.     uinfo.name[47] = '\0';
  169.     } else {
  170.     uinfo.home[0] = '\0';
  171.     return NULL;
  172.     }
  173.     if (gethostname(cptr, 256)) {
  174.     uinfo.host[0] = '\0';
  175.     uinfo.addr = 0;
  176.     return NULL;
  177.     } else {
  178.     strncpy(uinfo.host, cptr, 47);
  179.     uinfo.host[47] = '\0';
  180.     }
  181.     cptr[255]=0;
  182.     hostinfo = gethostbyname(cptr);
  183.     if (hostinfo == NULL) {
  184.     uinfo.addr = 0;
  185.     } else {
  186.     strncpy(uinfo.host, hostinfo->h_name, 47);
  187.     uinfo.host[47] = '\0';
  188.     uinfo.addr = (hostinfo->h_addr[0] << 24) |
  189.         (hostinfo->h_addr[1] << 16 ) |
  190.         (hostinfo->h_addr[2] << 8 ) |
  191.         hostinfo->h_addr[3];
  192.     }
  193.     
  194.     
  195.     /* find the users image */
  196.     strcpy(name, uinfo.home);
  197.     strcat(name, "/.bliximage");
  198.     f = fopen(name, "r");
  199.     if (f == NULL) {
  200.     /* try to use pandora's image search */
  201.     strcpy(name, uinfo.home);
  202.     strcat(name, "/.icons/login.icon");
  203.     f = fopen(name, "r");
  204.     if (f == NULL) {
  205.         strcpy(name, "/usr/local/lib/faces/");
  206.         strcat(name, uinfo.name);
  207.         f = fopen(name, "r");
  208.         if ( f == NULL) {
  209.         strcpy(name, "/usr/lib/faces/");
  210.         strcat(name, uinfo.name);
  211.         f = fopen(name, "r");
  212.         if ( f == NULL) {
  213.             *name = '\0';
  214.         }
  215.         }
  216.     }
  217.     }
  218.     if (f != NULL) 
  219.     fclose(f);
  220.     strncpy(uinfo.image, name, 128);
  221.     uinfo.image[128] = '\0';
  222.     /* check if user wants to use an alias instead of a real username */
  223.     strcpy(name, uinfo.home);
  224.     strcat(name, "/.blixalias");
  225.     f = fopen(name, "r");
  226.     if (f != NULL) {
  227.     fgets(alias, 48, f);
  228.     while ((s = strchr(alias,'\n')) != NULL) {
  229.         *s = ' ';
  230.     }
  231.     alias[47] = '\0';
  232.     strcpy(uinfo.name, alias);
  233.     fclose(f);
  234.     }
  235.     return &uinfo;
  236. }
  237.  
  238. void showscore(int clearin, int score,  int fadeout) {
  239.     int cnt;
  240.     int i;
  241.     float v1[3];
  242.     
  243.     uimode = MODE2D;
  244.     if (clearin) {
  245.     cpack(0x00000000);
  246.     switch_single();
  247.     clear();
  248.     }
  249.     /* fade in score display */
  250.     cpack(0x000022bb);
  251.     pushmatrix();
  252.     ortho2(0,1,0,1);
  253.     lmbind(MATERIAL, 0);
  254.     for (i=16; i>=0; i--) {
  255.     setpattern(i);
  256.     bgnqstrip();
  257.     v1[0] = 1; v1[1] = 0;cpack(0x000052ff);
  258.     v2f(v1);
  259.     v1[0] = 1; v1[1] = 1; cpack(0x000038ff);
  260.     v2f(v1);
  261.     v1[0] = 0; v1[1] = 0; cpack(0x000061ff);
  262.     v2f(v1);
  263.     v1[0] = 0; v1[1] = 1; cpack(0x000022bb);
  264.     v2f(v1);
  265.     gsync();
  266.     endqstrip();
  267.     gflush();
  268.     sginap(CLK_TCK/50);
  269.     }
  270.     if (initstat == -1 && score == WORLDHIGH) {
  271.     display_scene = SORRY;
  272.     } else {
  273.     display_scene = score;
  274.     }
  275.     draw_whatever2d();
  276.     cnt = 120;
  277.     while (do_event() == 0 && cnt-- ) {
  278.     sginap(CLK_TCK/10);
  279.     }
  280.     if (fadeout) {
  281.     cpack(0x000000);
  282.     for (i=16; i>= 0; i--) {
  283.         setpattern(i);
  284.         gsync();
  285.         clear();
  286.         gflush();
  287.         sginap(CLK_TCK/50);
  288.     }
  289.     sginap(CLK_TCK/2);
  290.     }
  291.     popmatrix();
  292.     display_scene = GAME;
  293.     uimode = MODE3D;
  294. }
  295.  
  296. void doscore(int score) {
  297.     userinfo_t *inf;
  298.     int scored = 0;
  299.     int i;
  300.     inf = getinf();
  301.     inf->score = score;
  302.     disable_pop();
  303.     if (doprivatescore(inf)) {
  304.     showscore(1, PRIVATHIGH, 0);
  305.     scored = 1;
  306.     }
  307.     if (dosystemscore(inf)) {
  308.     showscore((score != 1), SYSTEMHIGH, 0);
  309.     scored = 1;
  310.     }
  311.     if (noworld == 0 && doworldscore(inf) && initstat != -1) {
  312.     showscore((score != 1), WORLDHIGH, 0);
  313.     scored = 1;
  314.     } 
  315.     if (scored) {
  316.     cpack(0x000000);
  317.     for (i=16; i>= 0; i--) {
  318.         setpattern(i);
  319.         clear();
  320.         gflush();
  321.         sginap(CLK_TCK/50);
  322.     }
  323.     sginap(CLK_TCK/2);
  324.     }
  325.     enable_pop();
  326.     display_scene = GAME;
  327.     uimode = MODE3D;
  328. }
  329.  
  330. static int doprivatescore(userinfo_t *inf) {
  331.     static int first_time = 1;
  332.     int f;
  333.     
  334.     if (first_time) {
  335.     f = openprivatscore();
  336.     readscore(f, &privatlist);
  337.     privatlist.game++;
  338.     sort_score(&privatlist);
  339.     updatescore(&privatlist, inf);
  340.     if (f != -1) {
  341.         lseek(f, SEEK_SET, 0);
  342.         writescore(f, &privatlist);
  343.         close(f);
  344.     }
  345.     first_time = 0;
  346.     } else {
  347.     if (updatescore(&privatlist, inf)) {
  348.         f = openprivatscore();
  349.         if (f != -1) {
  350.         writescore(f, &privatlist);
  351.         close(f);
  352.         }
  353.         return 1;
  354.     }
  355.     }
  356.     return 0;
  357. }
  358.  
  359. /*___________________________________________________________________
  360.  |
  361.  | dosystemscore - keep track of system's best players
  362.  |
  363.  | it is different from the privat and world score, because it
  364.  | tries to read the systemscore file at every call. This is
  365.  | so you can play competion with your neighbour.
  366.  */
  367. static int dosystemscore(userinfo_t *inf) {
  368.     static int first_time = 1;
  369.     int f;
  370.     
  371.     if (first_time) {
  372.     /* read it */
  373.     f = opensystemscore();
  374.     readscore(f, &systemlist);
  375.     systemlist.game++;
  376.     sort_score(&systemlist);
  377.     updatescore(&systemlist, inf);
  378.     if (f != -1) {
  379.         lseek(f, SEEK_SET, 0);
  380.         writescore(f, &systemlist);
  381.         close(f);
  382.     }
  383.     first_time = 0;
  384.     } else {
  385.     f = opensystemscore();
  386.     if (f != -1) {
  387.         readscore(f, &systemlist);
  388.     }
  389.     if (updatescore(&systemlist, inf)) {
  390.         if (f != -1) {
  391.         lseek(f, SEEK_SET, 0);
  392.         writescore(f, &systemlist);
  393.         close(f);
  394.         }
  395.         return 1;
  396.     }
  397.     if (f != -1) {
  398.         close(f); 
  399.     }
  400.     }
  401.     return 0;
  402. }
  403.  
  404. int get_score(userinfo_t *inf) {
  405.     int f;
  406.     long imageid;
  407.     long imagesize;
  408.     char *imagedata;
  409.     int img;
  410.     int i;
  411.     struct stat statbuf;
  412.     char *slash;
  413.     char tmpstr[256];
  414.     mode_t cmask; 
  415.        
  416.     f = openworldscore();
  417.     readscore(f, &worldlist);
  418.     write_server("GSCR", -4);
  419.     write_server(&(worldlist.id), sizeof(long));
  420.     if (server_ready() == 0) {
  421.     read_serverscore(&worldlist);
  422.     closeserver();
  423.     for (i=0; i< 7; i++) {
  424.         /* check if image exists, otherwise request it */
  425.         if (worldlist.images[i] != NULL &&
  426.             *(worldlist.images[i]) != '\0' &&
  427.             stat(worldlist.images[i], &statbuf) != 0) {
  428.         slash = strrchr(worldlist.images[i], '/');
  429.         imageid = atoi(slash+1);
  430.         openserver();
  431.         write_server("GIMG", -4);
  432.         write_server(&imageid, sizeof(long));
  433.         if (server_ready() == 0) {
  434.             read_serverstr(tmpstr);
  435.             read_server(&imagesize, sizeof(long));
  436.             fprintf(stderr,"%s: receiving image %d bytes...",
  437.                 basename, (int) imagesize);
  438.             fflush(NULL);
  439.             if (imagesize != 0 && imagesize < 100000) {
  440.             imagedata = (char *)malloc(imagesize);
  441.             read_server(imagedata, -imagesize);
  442.             sprintf(worldlist.images[i],
  443.                 BLIXTMPDIR "/%s", tmpstr);
  444.             cmask = umask(0000);
  445.             img = open(worldlist.images[i],
  446.                 O_WRONLY | O_CREAT, 0666);
  447.             umask(cmask);
  448.             if (img >= 0) {
  449.                 write_data(img, imagedata, -imagesize);
  450.                 close(img);
  451.             } else {
  452.                 *(worldlist.images[i]) = '\0';
  453.             }
  454.             free(imagedata);
  455.             }
  456.             fprintf(stderr," done\n");
  457.         }
  458.         closeserver();
  459.         }
  460.     }
  461.     world_score_id = worldlist.id;
  462.     sort_score(&worldlist);
  463.     } else {
  464.     sort_score(&worldlist);
  465.     updatescore(&worldlist, inf);
  466.     }
  467.     if (f != -1) {
  468.     lseek(f, SEEK_SET, 0);
  469.     writescore(f, &worldlist);
  470.     close(f);
  471.     }
  472.     return 0;
  473. }
  474.  
  475. static int doworldscore(userinfo_t *inf) {
  476.     static int first_time = 1;
  477.     int f;
  478.     long yoursize;
  479.     char *yourimage;
  480.     int img;
  481.     struct stat buf;
  482.     
  483.     /* did we succeed in filling the world info ? */
  484.     if (world_score_id == -1)
  485.     return 0;
  486.     if (first_time) {
  487.     make_connect();
  488.     get_score(inf);
  489.     first_time = 0;
  490.     } else {
  491.     if (updatescore(&worldlist, inf)) {
  492.         if (openserver() == 0) {
  493.         write_server("PSCR", -4);
  494.         write_server(&(inf->score), sizeof(long));
  495.         write_server(inf->name, strlen(inf->name));
  496.         write_server(inf->host, strlen(inf->host));
  497.         write_server(&(inf->addr), sizeof(long));
  498.         if (inf->image != NULL && *(inf->image) != '\0') {
  499.             img = open(inf->image, O_RDONLY);
  500.             yoursize = 0;
  501.             if (img >= 0 && fstat(img, &buf) >= 0) {
  502.             yoursize = buf.st_size;
  503.             }
  504.             write_server(&yoursize, sizeof(yoursize));
  505.             if (yoursize != 0 && yoursize < 100000) {
  506.             yourimage = (char *)malloc(yoursize);
  507.             read_data(img, yourimage, -yoursize);
  508.             write_server(yourimage, -yoursize);
  509.             free(yourimage);
  510.             }
  511.         } else {
  512.             yoursize = 0;
  513.             write_server(&yoursize, sizeof(yoursize));
  514.         }
  515.         closeserver();
  516.         cleanup_images(&worldlist, BLIXTMPDIR, "world");    
  517.         }
  518.         f = openworldscore();
  519.         writescore(f, &worldlist);
  520.         close(f);
  521.         return 1;
  522.     }
  523.     }
  524.     return 0;
  525. }
  526.  
  527.  
  528. static void sort_score(scorelist_t *scorelist) {
  529.     int i,j;
  530.     char tmps[256];
  531.     long tmp;
  532.     
  533.     for (i = 1; i < 7; i++) {
  534.     j = i;
  535.     while (j > 0 && scorelist->scores[j-1] < scorelist->scores[j]) {
  536.         strcpy(tmps,scorelist->names[j]);
  537.         strcpy(scorelist->names[j], scorelist->names[j-1]);
  538.         strcpy(scorelist->names[j-1], tmps);
  539.         strcpy(tmps, scorelist->hosts[j]);
  540.         strcpy(scorelist->hosts[j], scorelist->hosts[j-1]);
  541.         strcpy(scorelist->hosts[j-1], tmps);
  542.         strcpy(tmps, scorelist->images[j]);
  543.         strcpy(scorelist->images[j], scorelist->images[j-1]);
  544.         strcpy(scorelist->images[j-1], tmps);
  545.         tmp = scorelist->scores[j];
  546.         scorelist->scores[j] = scorelist->scores[j-1];
  547.         scorelist->scores[j-1] = tmp;
  548.         tmp = scorelist->addrs[j];
  549.         scorelist->addrs[j] = scorelist->addrs[j-1];
  550.         scorelist->addrs[j-1] = tmp;
  551.         j--;
  552.     }
  553.     }
  554. }
  555.  
  556. static int updatescore( scorelist_t *scorelist, userinfo_t *inf) {
  557.  
  558.     int i;
  559.  
  560.     if (scorelist->scores[6] >= inf->score) {
  561.     return 0;
  562.     }
  563.     /* the high score list records the five persons
  564.      * with the highest scores, not the five highest scores.
  565.      * This is to get more variation on your screen:-)
  566.      */
  567.     i = 6;
  568.     if (scorelist != &privatlist) {
  569.     for (i=0; i< 6; i++) {
  570.         if (scorelist->addrs[i] == inf->addr && 
  571.             strcmp(scorelist->names[i], inf->name) == 0) {
  572.         break;
  573.         }
  574.     }
  575.     }
  576.     while (i > 0 && (scorelist->scores[i-1] < inf->score || 
  577.         ((scorelist->scores[i] == inf->score) &&
  578.           ((scorelist->addrs[i] != inf->addr) ||
  579.            (strcmp(scorelist->names[i], inf->name) != 0))
  580.         ))) {
  581.     strcpy(scorelist->names[i], scorelist->names[i-1]);
  582.     strcpy(scorelist->hosts[i], scorelist->hosts[i-1]);
  583.     strcpy(scorelist->images[i], scorelist->images[i-1]);
  584.     scorelist->scores[i] = scorelist->scores[i-1];
  585.     scorelist->addrs[i] = scorelist->addrs[i-1];
  586.     i--;
  587.     }
  588.     if (scorelist->scores[i] < inf->score || 
  589.         (scorelist->scores[i] == inf->score &&
  590.           (scorelist->addrs[i] != inf->addr ||
  591.            strcmp(scorelist->names[i], inf->name) != 0)
  592.         )) {
  593.     strcpy(scorelist->names[i], inf->name);
  594.     strcpy(scorelist->hosts[i], inf->host);
  595.     strcpy(scorelist->images[i], inf->image);    
  596.     scorelist->scores[i] = inf->score;
  597.     scorelist->addrs[i] = inf->addr;
  598.     return 1;
  599.     }
  600.     return 0;
  601. }
  602.  
  603. void printscore(char *head, scorelist_t *scorelist) {
  604.     int i;
  605.     fprintf(stderr, "%s\n", head);
  606.     fprintf(stderr, "games: %d id: %d\n", (int) scorelist->game, (int) scorelist->id);
  607.     for (i=0; i<7; i++) {
  608.     fprintf(stderr, "%s (%s) %d", scorelist->names[i],
  609.         scorelist->hosts[i], (int) scorelist->scores[i]);
  610.     if (scorelist->images[i] != NULL)
  611.         fprintf(stderr, " %s", scorelist->images[i]);
  612.     fprintf(stderr, "\n");
  613.     }
  614.     
  615. }
  616.  
  617.  
  618. void init_server(void) {
  619.     init_connect();
  620. }
  621.